package www.wen.com.common.lib.base.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.ViewDataBinding
import com.dylanc.loadinghelper.ViewType
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.core.CenterPopupView
import com.lxj.xpopup.impl.LoadingPopupView
import com.orhanobut.logger.Logger
import www.wen.com.common.lib.base.module.BaseViewModel
import www.wen.com.common.lib.data.entities.*
import www.wen.com.common.lib.extension.toast
import www.wen.com.common.lib.helper.loading.ErrorAdapter


/**
 * @author WEN
 * @Description: 这是一个通用加载框的Fragment，由viewModel通过livedata来发起,如果页面需要发起请求弹出标准加载框的请继承这个基类
 * @date 2020/11/25 17:49
 */
abstract class BaseLoadingFragment<K : ViewDataBinding> : BaseVMFragment<K>() {

    abstract val viewModel: BaseViewModel

    private var loadingPopup: LoadingPopupView? = null

    /**
     * 是否禁用loading ui的显示逻辑，
     * true为使用默认的加载ui（默认的加载ui也需要重写isEnableLoadingHelper() = true），
     * false则什么都不会发生
     */
    open val mIsEnableLoading = true

    /**
     * 是否使用自己的加载ui，需要mIsEnableLoading 设置为true，并重写customLoading()
     */
    open val mIsEnableUseCustomLoading = false

    /**
     * 同上
     */
    open val mIsEnableError = true

    open val mIsEnableUseCustomError = false

    /**
     * 同上
     */
    open val mIsEnableEmpty = true

    open val mIsEnableUseCustomEmpty = false

    /**
     * 同上
     */
    open val mIsEnableContent = true

    open val mIsEnableUseCustomContent = false

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = super.onCreateView(inflater, container, savedInstanceState)
        addObserve()
        addLoadingHelperObserve()
        lifecycle.addObserver(viewModel)
        return view
    }

    private fun addLoadingHelperObserve() {
        viewModel.loadingUiHelper.observe(viewLifecycleOwner) { loadingHelperUiState ->
            loadingHelperUiState?.run {
                Logger.i("loadingHelpType = ${loadingHelpType.name}")
                when (loadingHelpType) {
                    LoadingHelperType.LOADING -> {
                        loadingLogic(loadingHelperUiState)
                    }
                    LoadingHelperType.ERROR -> {
                        errorLogic(loadingHelperUiState)
                    }
                    LoadingHelperType.EMPTY -> {
                        emptyLogic(loadingHelperUiState)
                    }
                    LoadingHelperType.CONTENT -> {
                        contentLogic(loadingHelperUiState)
                    }
                }
            }
        }
    }

    private fun loadingLogic(loadingHelperUiState:LoadingHelperUiState) {
        if (!mIsEnableLoading) return

        if (mIsEnableUseCustomLoading) {
            customLoading()
        } else {
            if (isEnableLoadingHelper()) {
                mLoadingHelper!!.showLoadingView()
            }
        }
    }

    open fun customLoading() {

    }

    private fun errorLogic(loadingHelperUiState:LoadingHelperUiState) {
        if (!mIsEnableError) return

        if (mIsEnableUseCustomError) {
            customError()
        } else {
            if (isEnableLoadingHelper()) {
                val errorTip = loadingHelperUiState.stateData as String

                mLoadingHelper!!.getAdapter<ErrorAdapter>(ViewType.ERROR).run {
                    errorText = errorTip
                }
                mLoadingHelper!!.showErrorView()
            }
        }
    }

    open fun customError() {
        if (isEnableLoadingHelper()) {
            mLoadingHelper!!.showContentView()
        }
    }

    private fun emptyLogic(loadingHelperUiState:LoadingHelperUiState) {
        if (!mIsEnableEmpty) return

        if (mIsEnableUseCustomEmpty) {
            customEmpty()
        } else {
            if (isEnableLoadingHelper()) {
                mLoadingHelper!!.showEmptyView()
            }
        }
    }

    open fun customEmpty() {
        if (isEnableLoadingHelper()) {
            mLoadingHelper!!.showContentView()
        }
    }

    private fun contentLogic(loadingHelperUiState:LoadingHelperUiState) {
        if (!mIsEnableContent) return

        if (mIsEnableUseCustomContent) {
            customContent()
        } else {
            if (isEnableLoadingHelper()) {
                mLoadingHelper!!.showContentView()
            }
        }
    }

    open fun customContent() {}

    open fun addObserve() {
        viewModel.run {
            viewModel.loading.observe(viewLifecycleOwner, {
                if (it.stateType == StateType.LOADING_DIALOG) {
                    val data = it.stateData as LoadingDialog<String>
                    when (data.loadingDialogStateType) {
                        LoadingDialogStateType.LOADING -> {
                            showLoadingView(data.tip)
                        }
                        LoadingDialogStateType.SUCCESS -> {
                            if (it.stateData.isShowDialogTip) {
                                loadingPopup!!.postDelayed({
                                    if (it.stateData.isShowDialogTip) {
                                        loadingPopup!!.setTitle(data.tip)
                                    }
                                }, 0)
                                dismissLoadingView(0, runnable = Runnable {
                                    loading.value = UiStateCustom(stateData = LoadingDialog(data.tip, LoadingDialogStateType.DISMISS, data.isShowDialogTip, data.isShowToastTip, data.action))
                                })
                            } else if (it.stateData.isShowToastTip) {
                                dismissLoadingView(0, runnable = Runnable {
                                    loading.value = UiStateCustom(stateData = LoadingDialog(data.tip, LoadingDialogStateType.DISMISS, data.isShowDialogTip, data.isShowToastTip, data.action))
                                })
                            } else {
                                loading.value = UiStateCustom(stateData = LoadingDialog(data.tip, LoadingDialogStateType.DISMISS, data.isShowDialogTip, data.isShowToastTip, data.action))
                            }
                        }
                        LoadingDialogStateType.ERROR -> {

                            if (it.stateData.isShowDialogTip) {
                                loadingPopup!!.postDelayed({
                                    loadingPopup!!.setTitle(data.tip)
                                }, 0)
                            }
                            dismissLoadingView(0, runnable = Runnable {
                                loading.value = UiStateCustom(stateData = LoadingDialog(data.tip, LoadingDialogStateType.DISMISS, data.isShowDialogTip, data.isShowToastTip, data.action))
                            })
                        }
                        LoadingDialogStateType.DISMISS -> {
                            dismissLoadingView(0)
                            if (it.stateData.isShowToastTip) {
                                toast(data.tip)
                            }
                            it.stateData.action?.invoke()
                        }
                    }
                }
            })
        }

    }

    open fun showLoadingView(loadingText: String): CenterPopupView? {
        if (loadingPopup == null) {
            loadingPopup = XPopup
                    .Builder(requireActivity())
                    .dismissOnTouchOutside(false)
                    .dismissOnBackPressed(false)
                    .asLoading(loadingText)
                    .show() as LoadingPopupView
        }
        loadingPopup?.setTitle(loadingText)
        loadingPopup?.show()
        return loadingPopup
    }


    open fun dismissLoadingView(delay: Long, runnable: Runnable = Runnable {}) {
        loadingPopup?.run {
            loadingPopup!!.delayDismissWith(delay, runnable)
        }
    }

}